package com.tianxiabuyi.model.task;
import com.alibaba.fastjson.TypeReference;
import com.tianxiabuyi.model.pojo.Examine;
import com.tianxiabuyi.persist.DBTools;
import com.tianxiabuyi.persist.QBuilder;
import com.tianxiabuyi.persist.Where;
import com.tianxiabuyi.utils.DateUtil;
import com.tianxiabuyi.utils.HttpUtil;
import com.tianxiabuyi.utils.JSONUtil;
import com.tianxiabuyi.utils.Tools;

import java.net.URLEncoder;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 检验数据抓取任务类
 * Created by yanghaixiao on 2017/6/12.
 */
public class ExamineTask extends AbstractTask {
    private String name = "";     // 患者姓名
    private String cardNumber = "";  // 身份证号
    private String checkNumber = ""; // 检查单号,条码号，就诊号（体检编号等等）
    private Integer hospital = 0;   // 同步数据的医院 0表示全部合作医院

    @Override
    public void run() {
        switch (hospital)  {
            case 0:{
                 sdfey(cardNumber, name, "", "");
            }
            break;
            case 1000:{
                String now = DateUtil.formatDate(new Date());
                sdfyy(checkNumber, cardNumber, lastYear(now), now);
            }
            break;
            case 1002:{
                sdfey(cardNumber, name, "", "");
            }
            break;
            case 1010:{
                smh(checkNumber, cardNumber);
            }
            break;
            case 1014:{
                xcrmyy(checkNumber,name, cardNumber);
            }
            break;
            default:{
               System.out.println(String.format("暂时不支持该医院(%s)检验数据的同步", new Object[]{hospital}));
            }
            break;
        }


    }

    // 苏大附二院，检验数据
    void sdfey(String cardNumber, String name, String tmh, String zyh) {
        Map<String, String> map = new HashMap<String, String>();
        map.put("sfz", cardNumber);
        map.put("name", name);
        map.put("tmh", tmh);
        String json = HttpUtil.post("http://221.224.34.163:7071/patient/examine/list.jsp", map);
        List<Map> list = JSONUtil.fromJson(json, new TypeReference<List<Map>>() {
        });
        List<Examine> allList = new ArrayList<Examine>();
        List<String> sampList = QBuilder.db("basedb").select("sampleNo").from("Examine").where(new Where("hospital=", 1002)).query().getResultObj();
        // 如果检验记录条码号已存在，跳过不再存储
        Iterator it = list.iterator();
        while (it.hasNext()) {
            Map tt = (Map) it.next();
            if (sampList.contains(Tools.getDesc(tt.get("tmh")))) {
                it.remove();
            }
        }
        for (Map tMap : list) {
            map.put("tmh", Tools.getDesc(tMap.get("tmh")));
            json = HttpUtil.post("http://221.224.34.163:7071/patient/examine/show.jsp", map);
            List<Map> showList = JSONUtil.fromJson(json, new TypeReference<List<Map>>() {
            });
            for (Map showMap : showList) {
                Examine examine = new Examine();
                examine.setHospital(1002);
                examine.setSampleNo(Tools.getDesc(showMap.get("tmh"), ""));
                examine.setItemUnit(Tools.getDesc(showMap.get("dw"), ""));
                examine.setDescription(Tools.getDesc(showMap.get("ts"), ""));
                examine.setParentItemName(Tools.getDesc(showMap.get("bblx"), ""));
                examine.setReferDesc(Tools.getDesc(showMap.get("ckz"), ""));
                examine.setPatientId(Tools.getDesc(showMap.get("ybh"), ""));
                examine.setResult(Tools.getDesc(showMap.get("jyz"), ""));
                examine.setReceiveTime(Tools.getDesc(showMap.get("bgsj"), ""));
                examine.setCardNumber(Tools.getDesc(showMap.get("sfz"), ""));
                examine.setItemName(Tools.getDesc(showMap.get("mc"), ""));
                examine.setPatientName(Tools.getDesc(showMap.get("name"), ""));
                examine.setJson(showMap);          
                examine.setParentItemId(Tools.getPinYin(examine.getParentItemName()));
                allList.add(examine);
            }
        }
        //System.out.println(allList);
        if (allList.size() != 0) {
            DBTools.db("basedb").addItem(allList);
        }
    }

    // 苏州市相城人民医院，检验数据
    void xcrmyy(String tjbh, String name, String cardNumber) {
        Map map = new HashMap();
        map.put("tjbh", tjbh);
        map.put("name", name);
        String json = HttpUtil.post("http://192.168.1.203:8080/api/examine_transfer.jsp", map);
        List<Examine> list = JSONUtil.fromJson(json, new TypeReference<List<Examine>>() {
        });
        List<String> sampList = QBuilder.db("basedb").select("sampleNo").from("Examine").where(new Where("hospital=", 1014)).query().getResultObj();
        // 如果检验记录条码号已存在，跳过不再存储
        Iterator<Examine> it = list.iterator();
        while (it.hasNext()) {
            Examine ex = it.next();
            ex.setCardNumber(cardNumber);
            if (sampList.contains(ex.getSampleNo())) {
                it.remove();
            }
        }
        if (list.size() != 0) {
            DBTools.db("basedb").addItem(list);
        }
    }

    // 去空格
    public String trim(String str) {
        if (str == null) {
            return null;
        }
        str = str.replace((char) 12288, ' ');
        str = str.replaceAll("\\s*|\t|\r|\n", "").trim();
        return str;
    }

    // 获取两个日期中间所有日期（包括头尾）
    List<String> peroid(String start, String end) {
        DateFormat FORMATTER = new SimpleDateFormat("yyyy-MM-dd");
        Calendar startDay = Calendar.getInstance();
        Calendar endDay = Calendar.getInstance();
        try {
            startDay.setTime(FORMATTER.parse(start));
            endDay.setTime(FORMATTER.parse(end));
        } catch (Exception e) {

        }
        List<String> list = new ArrayList<String>();
        if (startDay.compareTo(endDay) >= 0) {
            return list;
        }
        Calendar currentPrintDay = startDay;
        while (true) {
            list.add(FORMATTER.format(currentPrintDay.getTime()));
            currentPrintDay.add(Calendar.DATE, 1);
            if (currentPrintDay.compareTo(endDay) == 0) {
                break;
            }
        }
        list.add(FORMATTER.format(currentPrintDay.getTime()));
        return list;
    }

    String lastYear(String date) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Calendar c = Calendar.getInstance();
        try {
            c.setTime((Date) sdf.parse(date));
        } catch (Exception e) {
            e.printStackTrace();
        }
        c.add(Calendar.YEAR, -1);
        return sdf.format(c.getTime());
    }

    // 苏大附一院，检验设置开始日期，结束日期
   void sdfyy(String clinicNumber, String cardNumber, String start, String end) {
        List<String> list = peroid(start, end);
        for (String date : list) {
            sdfyy(clinicNumber, cardNumber, date);
            try {
                Thread.sleep(1000);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    // 苏大附一院，检验查询
    void sdfyy(String clinicNumber, String cardNumber, String date) {
        String url = "http://www.sdfyy.cn/tools/LisReport.aspx";
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Long a = System.currentTimeMillis();
        String poid = clinicNumber.replaceAll("－", "-");
        poid = poid.substring(0, 1).toUpperCase() + poid.substring(1);
        poid = trim(poid);
        Long c = System.currentTimeMillis();
        String html = HttpUtil.get(url, "UTF-8");
        if ("".equals(html)) {
            return;
        }
        String remain = html.substring(html.indexOf("__VIEWSTATE"), html.length());
        String vstate = remain.substring(remain.indexOf("value=\"") + 7, remain.indexOf("/>")).trim();
        vstate = vstate.substring(0, vstate.length() - 1);
        try {
            vstate = URLEncoder.encode(vstate, "UTF-8");
        } catch (Exception e) {

        }
        remain = remain.substring(remain.indexOf("__EVENTVALIDATION"), remain.length());
        String evalid = remain.substring(remain.indexOf("value=\"") + 7, remain.indexOf("/>")).trim();
        evalid = evalid.substring(0, evalid.length() - 1);
        try {
            evalid = URLEncoder.encode(evalid, "UTF-8");
        } catch (Exception e) {

        }
        String pidKey = "ctl00$MainContent$txt_patient_id";
        String dateKey = "ctl00$MainContent$Txt1DateFrom";
        String url2 = url + "?__VIEWSTATE=" + vstate + "&__EVENTVALIDATION=" + evalid + "&__EVENTTARGET=&__EVENTARGUMENT=&" + pidKey + "=" + poid + "&" + dateKey + "=" + date + "&ctl00%24MainContent%24btn_search=%C2%A0%C2%A0";
        String resultHtml = HttpUtil.get(url2);
        org.jsoup.nodes.Document nameDocument = org.jsoup.Jsoup.parse(resultHtml);
        String patientName = nameDocument.select("#MainContent_lbl_patient_name").text();
        // 项目集合
        List<HashMap<String, Object>> projectList = new ArrayList<HashMap<String, Object>>();
        if (resultHtml != null && resultHtml.indexOf("<table") > 0) {
            String vTable = resultHtml.substring(resultHtml.indexOf("<table"), resultHtml.indexOf("</table>") + 8);
            String[] keys = {"project", "name", "jc", "result", "ms", "unit", "bz", "doctor"};
            List<HashMap<String, String>> list = new ArrayList<HashMap<String, String>>();
            org.jsoup.nodes.Document document = org.jsoup.Jsoup.parse(vTable);
            org.jsoup.select.Elements trElements = document.select("table").select("tr");
            trElements.remove(0);
            for (int i = 0; i < trElements.size(); i++) {
                org.jsoup.nodes.Element trElement = trElements.get(i);
                org.jsoup.select.Elements tdElements = trElement.select("input");
                HashMap<String, String> contentMap = new HashMap<String, String>();
                for (int j = 0; j < tdElements.size(); j++) {
                    org.jsoup.nodes.Element tdEmlment = tdElements.get(j);
                    String val = tdEmlment.attr("value").replaceAll(":", "：");
                    val = trim(val);
                    contentMap.put(keys[j], val);
                }
                list.add(contentMap);
            }
            Map<String, List<Map<String, String>>> realMap = new LinkedHashMap<String, List<Map<String, String>>>();
            for (int i = 0; i < list.size(); i++) {
                HashMap<String, String> m = list.get(i);
                String projectName = m.get(keys[0]);
                if (realMap.get(projectName) == null) {
                    List<Map<String, String>> newList = new ArrayList<Map<String, String>>();
                    newList.add(m);
                    realMap.put(projectName, newList);
                } else {
                    List<Map<String, String>> newList = realMap.get(projectName);
                    newList.add(m);
                    realMap.put(projectName, newList);
                }
            }
            for (Map.Entry<String, List<Map<String, String>>> m : realMap.entrySet()) {
                HashMap<String, Object> map = new HashMap<String, Object>();
                List<Map<String, String>> cList = m.getValue();
                // 标题
                if (cList.size() > 1) {
                    map.put("tableName", m.getKey()); // 项目名称
                    // 移除第一个项目名称标题
                    cList.remove(0);
                    map.put("content", cList);
                    projectList.add(map);
                }
            }
        }
        List<Examine> allList = new ArrayList<Examine>();
        for (Map map : projectList) {
            List<Map> exList = (List<Map>) map.get("content");
            for (Map content : exList) {
                Examine ex = new Examine();
                ex.setParentItemName(Tools.getDesc(content.get("project"), ""));
                ex.setItemName(Tools.getDesc(content.get("name"), ""));
                ex.setItemUnit(Tools.getDesc(content.get("unit"), ""));
                ex.setResult(Tools.getDesc(content.get("result"), ""));
                ex.setReferDesc(Tools.getDesc(content.get("bz"), ""));
                ex.setDescription(Tools.getDesc(content.get("ms"), ""));
                ex.setJson(content);
                ex.setHospital(1000);
                ex.setPatientName(patientName);
                ex.setReceiveTime(date);
                ex.setPatientId(clinicNumber);
                ex.setCardNumber(cardNumber);
                // 设置流水条码
                ex.setSampleNo(date + Tools.getPinYin(ex.getParentItemName()));
                allList.add(ex);
            }
        }
        List<String> sampList = QBuilder.db("basedb").select("sampleNo").from("Examine").where(new Where("hospital=", 1000)).query().getResultObj();
        // 如果检验记录条码号已存在，跳过不再存储
        Iterator<Examine> it = allList.iterator();
        while (it.hasNext()) {
            Examine ex = it.next();
            if (sampList.contains(ex.getSampleNo())) {
                it.remove();
            }
        }
        DBTools.db("basedb").addItem(allList);
    }

    /**
     * 苏州市立医院，检验数据
     *
     * @param patientId  就诊卡号
     * @param cardNumber 身份证号
     */
    void smh(String patientId, String cardNumber) {
        QBuilder.db("basedb").execHQL("update Examine set cardNumber='" + cardNumber + "' where hospital=1010 and patientId='" + patientId + "'");
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getCardNumber() {
        return cardNumber;
    }

    public void setCardNumber(String cardNumber) {
        this.cardNumber = cardNumber;
    }

    public String getCheckNumber() {
        return checkNumber;
    }

    public void setCheckNumber(String checkNumber) {
        this.checkNumber = checkNumber;
    }

    public Integer getHospital() {
        return hospital;
    }

    public void setHospital(Integer hospital) {
        this.hospital = hospital;
    }

    public ExamineTask(String name, String cardNumber, String checkNumber, Integer hospital, Object... parameters) {
        super(parameters);
        this.name = name;
        this.cardNumber = cardNumber;
        this.checkNumber = checkNumber;
        this.hospital = hospital;
    }
}
